#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct pair
{
  int value;
  int count;
};
#define MaxPair 1005
struct pair input[MaxPair];
struct pair output[MaxPair*2];
void export(int width);
void solve(int width,int height);
void solveOne(int total);
int main(int argc, char *argv[])
{
  int width=0,total=0;
  int i=0,j=0,k=0;
  while(1)
    {
      scanf("%d",&width);
      //end of file
      if(width==0)
	{	
	  printf ("0\n");
	  return;
	}
      //input sample
      while(1)
	{
	  scanf("%d%d",&(input[i].value),&(input[i].count));
	  total+=input[i].count;
	  if(input[i].count==0)
	    {
	      break;
	    }
	  i++;
	}
      i=0;
      /* if(width==1&&total!=1) */
      /* 	{ */
      /* 	  solveOne(total); */
      /* 	} */
      /* else */
      solve(width,total);
      export(width);
      total=0;
    }
  return 0;
}
int returnMaxDiff(int *array)
{
  int i=0;
  int result=0,absv=0;
  for(i=0;i<9;i++)
    {
      if(array[i]==-1)
	{
	  continue;
	}
      if(result<(absv=abs(array[4]-array[i])))
	result = absv;
    }
  return result;
}
void export(int width)
{
  int i=0;
  printf ("%d\n",width);
  while(1)
    {
      printf ("%d %d\n",output[i].value,output[i].count);
      if(output[i].count==0)
	{
	  return;
	}
      output[i].value=0;
      output[i].count=0;
      i++;
    }
}
struct position{
  int index;
  //if pos == -1 shows that it is out of top or bottom border at current time;
  int pos;
};
struct position p[9] ={0,-1};
void getPos(int pixelTillNow,struct position* pos)
{
  int i=0;
  pos->index=0;
  pos->pos=0;
  while(1)
    {
      if(i+input[pos->index].count<pixelTillNow)
	{
	  i+=input[pos->index].count;
	  pos->index++;
	  if(input[pos->index].count==0)
	    {
	      pos->pos=-1;
	      return;
	    }
	}
      else
	{
	  //not enough to increase a index
	  break;
	}
    }
  //increase the rest
  pos->pos+=pixelTillNow-i;
  if(pos->pos==input[pos->index].count)
    {
      pos->index++;
      pos->pos=0;
    }
}
void step()
{
  int i=0;
  for(i=0;i<9;i++)
    {
      if(input[p[i].index].count==0)
	{
	  p[i].pos=-1;
	}

      if(p[i].pos!=-1)
	p[i].pos++;
      if(input[p[i].index].count==p[i].pos)
	{
	  p[i].index++;
	  p[i].pos=0;
	}
      if(input[p[i].index].count==0)
	{
	  p[i].pos=-1;
	}
    }
}
/* void solveOne(total) */
/* { */
/*   solve(total,total); */
/* } */
void solve(int width,int total)
{
  int posX=0,posY=0;
  int i=0;
  int indexOut=0;
  int height = total/width;
  
  if(total%width!=0)
    {
      height++;
    }
  for(i=0;i<9;i++)
    {
      p[i].index=0;
      p[i].pos=-1;
    }

#define repeatNum(i) (input[p[i].index].count-p[i].pos)
#define repeatLong(i) (repeatNum(i)>5)
#define repeatAwhile(i) (p[i].pos>5)
#define isBorderTop (posY==0)
#define isBorderBottom (posY==height-1)

  while(input[p[4].index].count!=0)
    {
      int array[9]={0};
      //init
            //slice left 
      if(posX==0)
	{
	  array[0]=-1;
	  array[3]=-1;
	  array[6]=-1;
	}
      //slice right
      if(posX==width-1)
	{
	  array[2]=-1;
	  array[5]=-1;
	  array[8]=-1;
	}
      //slice up

      if(posY==0)
	{
	  array[0] =-1;
	  array[1] =-1;
	  array[2] =-1;
	  //stop top pos temprory
	  p[0].pos=-1;
	  p[1].pos=-1;
	  p[2].pos=-1;
	  

	  if(posX==0)
	    {
	      //start middle mid right bottom-mid bottom right
	      p[4].pos = 0;
	      getPos(1,&p[5]);
	      getPos(width,&p[7]);

	      getPos(width+1,&p[8]);
	    }


	  if(posX==1)
	    {
	      p[3].pos=0;
	      getPos(width,&p[6]);
	    }
	}
      

      if(posY==1)
	{
	  if(posX==0)
	    {
	      //start top right and top mid
	      p[1].pos=0;
	      getPos(1,&p[2]);
	    }
	  if(posX==1)
	    {
	      //start top left
	      p[0].pos=0;
	    }
	}
      //slice down

      if(posY==height-1)
	{
	  array[6]=-1;
	  array[7]=-1;
	  array[8]=-1;
	  //set bottom pos to -1
	  p[6].pos=-1;
	  p[7].pos=-1;
	  p[8].pos=-1;
	}

      //extreme repeat optimize with low width
      if(//beginning of a line not the top line1
      	 posX==0&&posY>1&&posY<height-2&&
      	 //many same pixels
      	 //and this means the bottom pixel have the same value as middle
      	 //more than 2 means at least 3(there are same line below the even bottom)
      	 (input[p[4].index].count-p[4].pos)>2*width&&
      	 //output have been in zero for a while(a line)
      	 //and this meas the top pixel is the same as middel
      	 /**mistake forget to judge value==0**/
      	 output[indexOut].count>=width&&output[indexOut].value==0)
      	{
	  printf ("posY = %d\n",posY);
	  int i=0;
      	  int plusPos = (input[p[4].index].count-p[4].pos)-2*width;
      	  //add outinput's count
      	  output[indexOut].count+=plusPos;
      	  //add every 9 pixels pos
      	  for(i=0;i<9;i++)
      	    {
	      if(p[i].pos==-1)
		{
		  printf ("ro\n");
		  continue;
		}
	      p[i].pos+=plusPos;
      	    }
	  posY+=plusPos/width;
	  printf ("posY = %d\n",posY);
	  printf ("posY plus = %d\n",plusPos/width);
	  continue;
	}

      //extreme width optimize
      if(//top-left mid-left bottom-left repeat long
	 // if it's border neglect it
	 (isBorderTop||(repeatLong(0)&&repeatAwhile(0)))&&
	 (repeatLong(3)&&repeatAwhile(3))&&
	 (isBorderBottom||(repeatLong(6)&&repeatAwhile(6)))&&
	 //and output value repeat for awhile which meas
	 //repeatLong's pixel has been repeat for a while
	 //no need to be ZERO
	 output[indexOut].count>5&&posX>5
	 )
	{
	  //will not over a line;
	  int Min = repeatNum(5)-1;
	  if(!isBorderTop)
	    if(Min>repeatNum(2)-1)
	      Min=repeatNum(2)-1;
	  if(!isBorderBottom)
	    if(Min>repeatNum(8)-1)
	      Min=repeatNum(8)-1;
	  if(Min>width-posX-3)
	    {
	      Min=width-posX-3;
	    }
	  //calculate output
	  if(Min>0)
	    {
    
	      output[indexOut].count+=Min;
	      //move 9 pixels
	      if(!isBorderTop)
		for(i=0;i<3;i++)
		  {
		    p[i].pos+=Min;
		  }
	      for(i=3;i<6;i++)
		{
		  p[i].pos+=Min;
		}
	      if(!isBorderBottom)
		for(i=6;i<9;i++)
		  {
		    p[i].pos+=Min;
		  }

	      //set posX
	      posX+=Min;
	      continue;
	    }s
	}
      //
      //normal solution
      //calculate
      for(i=0;i<9;i++)
	{
	  if(p[i].pos==-1||array[i]==-1)
	    {
	      if(posX==3)
		{
		  
		}
	      array[i]=-1;
	      continue;
	    }
	  array[i] = input[p[i].index].value;
	}
      if(output[indexOut].value==returnMaxDiff(array))
	{
	  output[indexOut].count++;
	}
      else
	{
	  if(posX!=0||posY!=0)
	    {
	      indexOut++;
	    }
	  output[indexOut].value=returnMaxDiff(array);
	  /**forgot to set count = 1 here**/
	  output[indexOut].count=1;
	  
	}
      //next step;
      /* if(posX==0&&posY==10) */
      /* 	{ */
      /* 	  printf ("result is\n"); */
      /* 	  for(i=0;i<9;i++) */
      /* 	    { */
      /* 	      printf ("array %d is %d\n",i,array[i]); */
      /* 	    } */
      /* 	  printf ("indexOut.count=%d\n",output[indexOut].count); */

      /* 	} */

      step();
      posX++;
      /**mistake posY++here**/
      if(posX==width)
	{
	  posX=0;
	  posY++;
	}
      /* if(posX==width&&posY==height) */
      /* 	{ */
      /* 	  break; */
      /* 	} */
    }
  output[++indexOut].count=0;
  output[indexOut].value=0;
}
